package com.itheima.d4_tcp1;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 *  目标：完成TCP通信快速入门-客户端开发：实现1发1收。
 *
 *  TCP通信
 * 特点：面向连接、可靠通信。
 * 通信双方事先会采用“三次握手”方式建立可靠连接，实现端到端的通信；底层能保证数据成功传给服务端。
 * Java提供了一个java.net.Socket类来实现TCP通信。
 *
 * TCP通信之-客户端开发
 * 客户端程序就是通过java.net包下的Socket类来实现的。
 *      构造器
 * public Socket(String host , int port)   根据指定的服务器ip、端口号请求与服务端建立连接，连接通过，就获得了客户端socket
 *      方法
 * public OutputStream getOutputStream()        获得字节输出流对象
 * public InputStream getInputStream()          获得字节输入流对象
 *
 * 客户端发送消息
 * 客户端实现步骤
 * 创建客户端的Socket对象，请求与服务端的连接。
 * 使用socket对象调用getOutputStream()方法得到字节输出流。
 * 使用字节输出流完成数据的发送。
 * 释放资源：关闭socket管道。
 *
 *TCP通信，客户端的代表类是谁？
 * Socket类
 * public Socket(String host , int port)
 *
 * TCP通信，如何使用Socket管道发送、接收数据 ?
 * OutputStream getOutputStream()：获得字节输出流对象（发）
 * InputStream getInputStream()：获得字节输入流对象（收）
 *
 *
 * TCP通信-服务端程序的开发
 *  服务端是通过java.net包下的ServerSocket类来实现的。
 *  ServerSocket        构造器
 *  public ServerSocket(int port)       为服务端程序注册端口
 *          方法
 *  public Socket accept()  阻塞等待客户端的连接请求，一旦与某个客户端成功连接，则返回服务端这边的Socket对象。
 *
 * 服务端实现接收消息
 *  服务端实现步骤
 * 创建ServerSocket对象，注册服务端端口。
 * 调用ServerSocket对象的accept()方法，等待客户端的连接，并得到Socket管道对象。
 * 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
 * 释放资源：关闭socket管道
 *
 * TCP通信服务端用的类是谁？
 * ServerSocket类,注册端口。
 * 调用accept()方法阻塞等待接收客户端连接。得到Socket对象。
 * TCP通信服务端的开发步骤是什么？
 */
public class Client {
    public static void main(String[] args) throws Exception {
        // 1、创建Socket对象，并同时请求与服务端程序的连接。
        Socket socket = new Socket("127.0.0.1", 8888);    //直接抛出异常
        // 并且和udp协议不一样,这里的端口号是指客户端去服务端的端口号，所以服务端和客户端两者的端口号要相匹配
        //后续服务端开发好了，一但接收客户端我这个地方的连接请求，那就可以得到一个socket对象，相当于得到一个socket通信管道

        // 2、从socket通信管道中得到一个字节输出流，用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        // 3、把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);

        // 4、开始写数据出去了
        dos.writeUTF("在一起，好吗？");    //这个方法磊哥说教过，我没印象
        //关闭数据输出流的时候，数据输出流是包装来了前面的低级字节输出流，关闭外部的包装流，会自动把内部包装的字节输出流也关闭
        dos.close();

        socket.close(); // 释放连接资源
    }
}
